var typeLib = require('../type')
var pathLib = require('path')
var flatten = require('arr-flatten')


module.exports = arrayFlat

/**
 * [递归 合并返回数据]
 * 强化版本的 flatten, 不要求参数是数组
 * 利用了concat的特性， 最终将所有的递归的结果，都合并到result遍历中返回
 * @param  {...[type]}  args          [description]
 * @return {[type]}     [description]
 */
function arrayFlat (... args) {
	var result = []

	var cur ;
	for (var i = 0; i < args.length; i++) {
		cur = args[i]
		if(Array.isArray(cur)) {
			result = result.concat(arrayFlat(...cur))
		} else {
			result = result.concat(cur)
		}
	}
	return result
}

/**
 * [递归 通过参数传递数据]
 * arr 参数必须是一个数组
 * 通过参数传递递归合并的数据
 * @param  {[type]} arr [description]
 * @return {[type]}     [description]
 */
function arrayFlatV1(arr) {
	var ret = []
	return flatten(arr, ret)

	// 将递归的结果用参数进行传递
	function flatten(arr, result = []) {
		var cur ;
		for (var i = 0; i < arr.length; i++) {
			cur = arr[i]
			if(Array.isArray(cur)) {
				 flatten(cur, result)
			} else {
				result.push(cur)
			}
		}
		return result
	}
}

(function(){
	var array = ['a', ['b', ['c']], 'd', ['e']]


	console.group()
	console.log( flatten(array) );
	console.groupEnd()

	console.log('\n-----------------------\n')

	console.group(pathLib.basename(__filename))
	console.log( arrayFlat(array) );
	console.log( arrayFlatV1(array) );
	console.groupEnd()

	console.log( arrayFlat(1, 23, 'a', ['b', ['c']], 'd', ['e']) );

	buildTest();
}) 




/**
 * 测试不同版本的函数，返回结果是否一致
 * @return {[type]} [description]
 */
function buildTest() {
	console.log(`\n------   buildTest ${pathLib.basename(__filename)} ... ------\n`)
	
	// console.log(isExitsFunction('arrayFlat'))
	// console.log(getTestFunList(arrayFlat))
	myTest(arrayFlat, ['a', ['b', ['c']], 'd', ['e']]);

	/**
	 * 测试不同版本的 函数返回的结果是否一致
	 * @param  {Function}  fn   [description]
	 * @param  {...[type]} args [description]
	 * @return {[type]}         [description]
	 */
	function myTest(fn, ...args) {
		var fnList = getTestFunList(fn)

		var result = []
		for (var i = 0; i < fnList.length; i++) {
			result.push(fnList[i](...args))
		}

		var trasResult = result.map(item => JSON.stringify(item))
		var uniqueTransResult = [... new Set(trasResult)]
		
		// 几组函数的结果 返回值相同
		if(uniqueTransResult.length === 1) {
			return true
		} else {
			console.group('myTest result')
			console.log(result)
			console.groupEnd()
			
			return false 
		}
	}



	/**
	 * 获取多个同一功能，不能实现的函数列表
	 * @param  {Function} fn [description]
	 * @return {[type]}      [description]
	 */
	function getTestFunList(fn) {
		if(typeof fn !== 'function') {
			throw new TypeError('the argument must be an  function ')
		}

		var fnList = [fn]
		var fnMore = null
		var x = 0 
		while(x ++ < 10 ) {
			var isBreak = false ;
			var fnArr = []
			// 不同版本的函数，命名符合一定的规则
			var fnNames = [ fn.name + x , fn.name + `V${x}`, fn.name + `v${x}` ]

			for (var i = 0; i < fnNames.length; i++) {
				fnMore =  isExitsFunction(fnNames[i])
				if(fnMore) {
					fnArr.push(fnMore)
					// fnMore = null
				}
			}

			// 没有找到一个函数
			if(fnArr.length === 0) {
				isBreak = true
			}
			
			fnList = fnList.concat(fnArr)
			if(isBreak) break
		}
		
		return  fnList
	}


	/**
	 * 判断一个函数(字符串)是否存在
	 * @param  {[type]}  funcName        [description]
	 * @param  {Boolean} transToFunction [description]
	 * @return {Boolean}                 [description]
	 */
	function isExitsFunction(funcName, transToFunction = true) {
	  try {
	  	var transFun = eval(funcName)
	    if (typeof(transFun) == "function") {
	      return transToFunction ? transFun : true
	    }
	  } catch(e) {}
	  return false 
	}
}
